using System;

namespace SharpMud.Server.Systems.Security
{
	public class Utility
	{
		public static System.Text.Encoding DefaultTextEncoding
		{
			get
			{
				return System.Text.Encoding.Default;
			}
		}

		public static System.Security.Cryptography.HashAlgorithm DefaultHashAlgorithm
		{
			get
			{
				return new System.Security.Cryptography.SHA512Managed();
			}
		}

		public static string MakeSecureKey(System.Guid guid, string key)
		{
			return MakeSecureKey(guid.ToString(),key);
		}

		public static string MakeSecureKey(string str1, string str2)
		{
			System.Security.Cryptography.HashAlgorithm hasher;
			hasher = DefaultHashAlgorithm;
			string blend = InterlaceStrings(str1,str2);
			string secureKey = DefaultTextEncoding.GetString(
				hasher.ComputeHash(DefaultTextEncoding.GetBytes(blend)));
			return secureKey;
		}

		public static string InterlaceStrings(string str1, string str2)
		{
			string r="";
			int n = (str1.Length>str2.Length ? str1.Length : str2.Length);
			for(int x=0;x<n;x++)
			{
				if(x<str1.Length && x<str2.Length)
				{
					r = r + str1[x] + str2[x];
					continue;
				}
				if(x<str1.Length && !(x<str2.Length))
				{
					r = r + str1[2];
					continue;
				}
				if(!(x<str1.Length) && x<str2.Length)
				{
					r = r + str2[2];
					continue;
				}
			}
			return r;
		}

		/// <summary>
		/// Adds two System.Guids, and normalizes resulting byte values to fit within
		/// the appropriate range.
		/// </summary>
		/// <param name="guid1">The first Guid addend</param>
		/// <param name="guid2">The second Guid addend</param>
		/// <returns>Returns the sum of the two Guids</returns>
		public static System.Guid AddGuids(System.Guid guid1, System.Guid guid2)
		{
			byte[] guid1BA = guid1.ToByteArray();
			byte[] guid2BA = guid2.ToByteArray();
			int byteCount = guid1BA.Length;
			byte[] guid3BA = new byte[byteCount];
			
			int currentByteValue=0;
			for(int currentByte=0;currentByte<byteCount;currentByte++)
			{
				currentByteValue = (int)((byte)guid1BA.GetValue(currentByte))
					+
					(int)((byte)guid2BA.GetValue(currentByte));
				
				while(currentByteValue>byte.MaxValue)
				{currentByteValue=currentByteValue-(byte.MaxValue-byte.MinValue);}
				while(currentByteValue<byte.MinValue)
				{currentByteValue=currentByteValue+(byte.MaxValue-byte.MinValue);}

				guid3BA.SetValue((byte)currentByteValue,currentByte);
			}
			return new System.Guid(guid3BA);
		}
	}
}
